/*
 * Classname IBrokerManagerHelpers.java
 * 
 * Version Information
 * Date May 3, 2006
 *
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.management.util;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.amsoft.iservice.icontact.util.IContactConstants;
import net.amsoft.iservice.ilink.util.ILinkConstants;
import net.amsoft.iservice.isso.hibernate.IBroker;
import net.amsoft.iservice.isso.hibernate.Principal;
import net.amsoft.iservice.isso.hibernate.Synonym;
import net.amsoft.iservice.isso.util.ISSOConstants;
import net.amsoft.iservice.util.exception.IServiceException;
import net.amsoft.iservice.util.exception.IServiceSystemException;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Order;

public class IBrokerManagerHelpers {
    
    private static Logger logger = Logger
    .getLogger(IBrokerManagerHelpers.class);
    
    /**
     * Returns the map of all the IBroker Admins
     * 
     * @param sIBrokerName
     * @param sPrincipal
     * @param oSession
     * @param oTransaction
     * @return Map
     * @throws IServiceException
     */
    public static Map verifyIfIsAdminISSO(String sIBrokerName,
            String sPrincipal, Session oSession, Transaction oTransaction)
            throws IServiceException {
        logger.debug("verifyIfIsAdminISSO() : Entry ");
        IBroker oIBroker = (IBroker) oSession.createCriteria(IBroker.class)
                .add(Expression.eq("serverName", sIBrokerName)).add(
                        Expression.eq("state", Short
                                .valueOf(IBrokerConstants.STATE_ACTIVE)))
                .uniqueResult();
        if (null == oIBroker) {
            logger.warn("verifyIfIsAdminISSO() : No admin found for IBroker " + sIBrokerName);
            throw new IServiceException(2004, false);
        } else
        {
            logger.info("verifyIfIsAdminISSO() : Found Admin for IBroker " + sIBrokerName);
            return oIBroker.getBrokerAdmin();
        }
    }

    /**
     * Returns the map of all the IBroker Admins
     * 
     * @param sIBrokerName
     * @param sPrincipal
     * @param oSession
     * @param oTransaction
     * @return Map
     * @throws IServiceException
     */
    public static Map verifyIfIsAdminIContact(String sIBrokerName,
            String sPrincipal, Session oSession, Transaction oTransaction)
            throws IServiceException {
        logger.debug("verifyIfIsAdminIContact() : Entry ");
        net.amsoft.iservice.icontact.hibernate.IBroker oIBroker = (net.amsoft.iservice.icontact.hibernate.IBroker) oSession
                .createCriteria(
                        net.amsoft.iservice.icontact.hibernate.IBroker.class).add(
                        Expression.eq("serverName", sIBrokerName)).add(
                        Expression.eq("state", Integer
                                .valueOf(IBrokerConstants.STATE_ACTIVE)))
                .uniqueResult();
        if (null == oIBroker) {
            logger.warn("verifyIfIsAdminIContact() : No admin found for IBroker " + sIBrokerName);
            throw new IServiceException(2004, false);
        } else
        {
            logger.info("verifyIfIsAdminIContact() : Found Admin for IBroker " + sIBrokerName);
            return oIBroker.getBrokerAdmin();
        }
    }

    /**
     * Returns the map of all the IBroker Admins
     * 
     * @param sIBrokerName
     * @param sPrincipal
     * @param oSession
     * @param oTransaction
     * @return Map
     * @throws IServiceException
     */
    public static Map verifyIfIsAdminILink(String sIBrokerName,
            String sPrincipal, Session oSession, Transaction oTransaction)
            throws IServiceException {
        logger.debug("verifyIfIsAdminILink() : Entry ");
        net.amsoft.iservice.ilink.hibernate.IBroker oIBroker = (net.amsoft.iservice.ilink.hibernate.IBroker) oSession
                .createCriteria(
                        net.amsoft.iservice.ilink.hibernate.IBroker.class).add(
                        Expression.eq("serverName", sIBrokerName)).add(
                        Expression.eq("state", Short
                                .valueOf(IBrokerConstants.STATE_ACTIVE)))
                .uniqueResult();
        if (null == oIBroker) {
            logger.warn("verifyIfIsAdminILink() : No admin found for IBroker " + sIBrokerName);
            throw new IServiceException(2004, false);
        } else
        {
            logger.info("verifyIfIsAdminILink() : Found Admin for IBroker " + sIBrokerName);
            return oIBroker.getBrokerAdmin();
        }
    }

    /**
     * Fetches the Ibroker for the ISSO service
     * 
     * @param sServerName
     * @param oSession
     * @param oTransaction
     * @return IBroker
     * @throws IServiceException
     */
    public static IBroker fetchIBrokerISSO(String sServerName,
            Session oSession, Transaction oTransaction)
            throws IServiceException {
        logger.debug("fetchIBrokerISSO() : Entry ");
        IBroker oIBroker = null;
        oIBroker = (IBroker) oSession.createCriteria(IBroker.class).add(
                Expression.eq("serverName", sServerName)).add(
                Expression.eq("state", Short
                        .valueOf(IBrokerConstants.STATE_ACTIVE)))
                .uniqueResult();
        if (null == oIBroker) {
            logger.warn("fetchIBrokerISSO() : Found not IBroker " + sServerName);
            throw new IServiceException(2004, false);
        }
        logger.info("fetchIBrokerISSO() : Found IBroker " + sServerName);
        return (oIBroker);
    }

    /**
     * Fetches the Ibroker for the IContact service
     * 
     * @param sServerName
     * @param oSession
     * @param oTransaction
     * @return IBroker
     * @throws IServiceException
     */
    public static net.amsoft.iservice.icontact.hibernate.IBroker fetchIBrokerIContact(
            String sServerName, Session oSession, Transaction oTransaction)
            throws IServiceException {
        logger.debug("fetchIBrokerIContact() : Entry ");
        net.amsoft.iservice.icontact.hibernate.IBroker oIBroker = null;
        oIBroker = (net.amsoft.iservice.icontact.hibernate.IBroker) oSession
                .createCriteria(
                        net.amsoft.iservice.icontact.hibernate.IBroker.class).add(
                        Expression.eq("serverName", sServerName)).add(
                        Expression.eq("state", Integer
                                .valueOf(IBrokerConstants.STATE_ACTIVE)))
                .uniqueResult();
        if (null == oIBroker) {
            logger.warn("fetchIBrokerIContact() : Found not IBroker " + sServerName);
            throw new IServiceException(2004, false);
        }
        logger.info("fetchIBrokerIContact() : Found IBroker " + sServerName);
        return (oIBroker);
    }

    /**
     * Fetches the Ibroker for the ILink service
     * 
     * @param sServerName
     * @param oSession
     * @param oTransaction
     * @return IBroker
     * @throws IServiceException
     */
    public static net.amsoft.iservice.ilink.hibernate.IBroker fetchIBrokerILink(
            String sServerName, Session oSession, Transaction oTransaction)
            throws IServiceException {
        logger.debug("fetchIBrokerILink() : Entry ");
        net.amsoft.iservice.ilink.hibernate.IBroker oIBroker = null;
        oIBroker = (net.amsoft.iservice.ilink.hibernate.IBroker) oSession
                .createCriteria(
                        net.amsoft.iservice.ilink.hibernate.IBroker.class).add(
                        Expression.eq("serverName", sServerName)).add(
                        Expression.eq("state", Short
                                .valueOf(IBrokerConstants.STATE_ACTIVE)))
                .uniqueResult();
        
        if (null == oIBroker) {
            logger.warn("fetchIBrokerILink() : Found not IBroker " + sServerName);
            throw new IServiceException(2004, false);
        }
        logger.info("fetchIBrokerILink() : Found IBroker " + sServerName);
        return (oIBroker);
    }

    /**
     * fetches all the Ibrokers for the ISSO Service
     * 
     * @param oSession
     * @param oTransaction
     * @return List
     */
    public static List fetchAllIBrokersISSO(Session oSession,
            Transaction oTransaction) {
        logger.debug("fetchAllIBrokersISSO() : Entry ");
        Criteria oCriteria = oSession.createCriteria(IBroker.class);
        oCriteria.add(Expression.eq("state", Short
                .valueOf((short) IBrokerConstants.STATE_ACTIVE)));
        oCriteria.addOrder(Order.asc("id"));
        List oIBrokerList = oCriteria.list();
        logger.debug("fetchAllIBrokersISSO() : REturning list of " + oIBrokerList.size() +"Ibrokers");
        return oIBrokerList;
    }

    /**
     * fetches all the Ibrokers for the IContact Service
     * 
     * @param oSession
     * @param oTransaction
     * @return List
     */
    public static List fetchAllIBrokersIContact(Session oSession,
            Transaction oTransaction) {
        logger.debug("fetchAllIBrokersIContact() : Entry ");
        Criteria oCriteria = oSession
                .createCriteria(net.amsoft.iservice.icontact.hibernate.IBroker.class);
        oCriteria.add(Expression.eq("state", Integer
                .valueOf(IBrokerConstants.STATE_ACTIVE)));
        oCriteria.addOrder(Order.asc("id"));
        List oIBrokerList = oCriteria.list();
        logger.debug("fetchAllIBrokersIContact() : REturning list of " + oIBrokerList.size() +"Ibrokers");
        return oIBrokerList;
    }

    /**
     * fetches all the Ibrokers for the ILink Service
     * 
     * @param oSession
     * @param oTransaction
     * @return List
     */
    public static List fetchAllIBrokersILink(Session oSession,
            Transaction oTransaction) {
        logger.debug("fetchAllIBrokersILink() : Entry ");
        Criteria oCriteria = oSession
                .createCriteria(net.amsoft.iservice.ilink.hibernate.IBroker.class);
        oCriteria.add(Expression.eq("state", Short
                .valueOf((short) IBrokerConstants.STATE_ACTIVE)));
        oCriteria.addOrder(Order.asc("id"));
        List oIBrokerList = oCriteria.list();
        logger.debug("fetchAllIBrokersILink() : REturning list of " + oIBrokerList.size() +"Ibrokers");
        return oIBrokerList;
    }

    /**
     * 
     * @param sGlobalINumber
     * @param sSynonym
     * @param sIBrokerName
     * @param oSession
     * @return boolean
     * @throws IServiceException
     */
    public static boolean verifySynonymISSO(String sGlobalINumber,
            String sSynonym, String sIBrokerName, Session oSession)
            throws IServiceException {
        logger.debug("verifySynonymISSO() : Entry ");
        int iIBrokerId = 0;
        try {
            Synonym oGINSyn = (Synonym) oSession
                    .createCriteria(Synonym.class)
                    .add(Expression.eq("synonym", sGlobalINumber))
                    .add(
                            Expression
                                    .eq(
                                            "state",
                                            Short
                                                    .valueOf((short) ISSOConstants.STATE_ACTIVE)))
                    .uniqueResult();
            if (null == oGINSyn) {
                logger.warn("verifySynonymISSO() : No matching Global INumber found");
                throw new IServiceSystemException(2006);
            }
            Principal oPrincipal = oGINSyn.getPrincipal();
            // Check if principal state is active or not
            IBroker oIBroker = (IBroker) oSession.createCriteria(IBroker.class)
                    .add(Expression.eq("serverName", sIBrokerName)).add(
                            Expression.eq("state", Short
                                    .valueOf(ISSOConstants.STATE_ACTIVE)))
                    .uniqueResult();
            if (null == oIBroker) {
                logger.warn("verifySynonymISSO() : No matching IBroker found");
                throw new IServiceException(2004, false);
            }
            // Throw exception if Ibroker state not active
            if (oIBroker.getState() == ISSOConstants.STATE_ACTIVE) {
                iIBrokerId = oIBroker.getId().intValue();
            } else {
                logger.warn("verifySynonymISSO() : No matching Active IBroker found");
                throw new IServiceException(2004, false);
            }
            if (iIBrokerId == oPrincipal.getBroker().getId()) {
                if (oPrincipal.getState() == ISSOConstants.STATE_ACTIVE) {
                    Set oSynonyms = oPrincipal.getSynonyms();
                    for (Iterator oIter = oSynonyms.iterator(); oIter.hasNext();) {
                        Synonym oSynonym = (Synonym) oIter.next();
                        oSynonym.debug("sSynonym");
                        if (oSynonym.getSynonym().equals(sSynonym)) {
                            logger.info("verifySynonymISSO() : matching Synonym found returning true");
                            return true;
                        }
                    }
                }
            }
        } catch (IServiceException ise) {
            logger.warn("verifySynonymISSO() : Exception Caught ");
            if (!(ise.getErrorCode() == 2007) && !(ise.getErrorCode() == 2004))
                throw ise;
        }
        return false;
    }

    /**
     * 
     * @param sSynonym
     * @param sIBrokerName
     * @param oSession
     * @return boolean
     * @throws IServiceException
     */
    public static boolean verifySynonymILink(String sSynonym,
            String sIBrokerName, Session oSession) throws IServiceException {
        logger.debug("verifySynonymILink() : Entry ");
        net.amsoft.iservice.ilink.hibernate.IBroker oIBroker = new net.amsoft.iservice.ilink.hibernate.IBroker();
        Criteria oCriteria = oSession
                .createCriteria(net.amsoft.iservice.ilink.hibernate.IBroker.class);
        oCriteria.add(Expression.eq("serverName", sIBrokerName));
        oCriteria.add(Expression.eq("state", Short
                .valueOf(ILinkConstants.STATE_ACTIVE)));
        oIBroker = (net.amsoft.iservice.ilink.hibernate.IBroker) oCriteria
                .uniqueResult();
        if (null == oIBroker) {
            logger.warn("verifySynonymILink() : No matching IBrokerFound");
            throw new IServiceException(2004, false);
        }
        net.amsoft.iservice.ilink.hibernate.Synonym oSynonym = new net.amsoft.iservice.ilink.hibernate.Synonym();
        Criteria oCriteriaSyn = oSession
                .createCriteria(net.amsoft.iservice.ilink.hibernate.Synonym.class);
        oCriteriaSyn.add(Expression.eq("synonym", sSynonym));
        oCriteriaSyn.add(Expression.eq("state", Short
                .valueOf((short) ILinkConstants.STATE_ACTIVE)));
        oSynonym = (net.amsoft.iservice.ilink.hibernate.Synonym) oCriteriaSyn
                .uniqueResult();
        if (null == oSynonym){
            logger.warn("verifySynonymILink() : No matching Synonym Found");
            throw new IServiceException(2020, false);
        }
        if (oIBroker.getId().intValue() == oSynonym.getSubscriber().getBroker()
                .getId().intValue())
        {
            logger.info("verifySynonymILink() : Matching Synonym Found exiting with true value");
            return true;
        }
        return false;
    }

    /**
     * 
     * @param sGlobalINumber
     * @param sSynonym
     * @param sIBrokerName
     * @param oSession
     * @return boolean
     * @throws IServiceException
     */
    public static boolean verifySynonymIContact(String sGlobalINumber,
            String sSynonym, String sIBrokerName ,
            Session oSession)
            throws IServiceException {
        logger.debug("verifySynonymIContact() : Entry ");
        net.amsoft.iservice.icontact.hibernate.Synonym oSynonym = new net.amsoft.iservice.icontact.hibernate.Synonym();
        oSynonym = (net.amsoft.iservice.icontact.hibernate.Synonym) oSession
                .createCriteria(
                        net.amsoft.iservice.icontact.hibernate.Synonym.class).add(
                        Expression.eq("name", sSynonym)).add(
                        Expression.eq("state", Integer
                                .valueOf(IContactConstants.ACTIVE)))
                .uniqueResult();
        oSynonym.update();
        if (oSynonym != null
                && oSynonym.getName().equals(sGlobalINumber)
                && oSynonym.getSubscriber().getBroker().getServerName().equals(
                        sIBrokerName)) {
            logger.info("verifySynonymIContact(): exit with true found Synonym " + sSynonym);
            return true;
        } else if (oSynonym != null
                && oSynonym.getGlobalINumber().getName().equals(sGlobalINumber)
                && oSynonym.getSubscriber().getBroker().getServerName().equals(
                        sIBrokerName)) {
            logger.info("verifySynonymIContact(): exit with true found Synonym " + sGlobalINumber);
            return true;
        } else {
            logger.warn("verifySynonymIContact(): exit with false No matching  Synonym found " );
            throw new IServiceException(2020, false);
        }
    }
}
